import { useAppStore, useRouteStore, useTabsStore } from '..'
import type { AccountLoginReq, PhoneLoginReq } from '@/apis'
import {
  getUserInfo,
  loginByAccount as loginByAccountApi,
  loginByPhone as loginByPhoneApi,
  loginBySocial as loginBySocialApi,
  logout as logoutApi,
} from '@/apis'
import { resetRouter } from '@/router'
import { clearToken, getToken, setToken } from '@/utils/auth'
import getAvatar from '@/utils/avatar'

export const useUserStore = defineStore('user', () => {
  // 认证token
  const token = ref(getToken() || '')
  // 当前角色权限标识集合
  const permissions = ref<Set<string>>(new Set())
  // 用户信息
  const userInfo = reactive<any>({
    name: '',
    avatar: '',
    gender: 1,
  })

  // 刷新用户信息
  const refreshUserInfo = async () => {
    const res = await getUserInfo()
    Object.assign(userInfo, res.userInfo)
    userInfo.avatar = getAvatar(userInfo.avatar, userInfo.gender)
    permissions.value = new Set(res.resourceCodeList)
  }

  /**
   * 是否有所有资源的权限
   * @param code 资源编码
   * @returns 是否有权限
   */
  const hasPermission = (code: string | string[] | undefined): boolean => {
    if (!code || permissions.value.has('*')) {
      return true
    }
    if (Array.isArray(code)) {
      return !code.some(item => !permissions.value.has(item))
    }
    return permissions.value.has(code)
  }

  /**
   * 是否有任意权限
   * @param code 资源编码或资源编码数组
   * @returns 是否有权限
   */
  const hasAnyPermission = (code: string | string[] | undefined): boolean => {
    if (!code || permissions.value.has('*')) {
      return true
    }
    if (Array.isArray(code)) {
      return code.length === 0 || code.some(item => permissions.value.has(item))
    }
    return permissions.value.has(code)
  }

  // 登录
  const loginByAccount = async (req: AccountLoginReq) => {
    const res = await loginByAccountApi(req)
    setToken(res.token)
    token.value = res.token
  }

  // 登录
  const loginByPhone = async (req: PhoneLoginReq) => {
    const res = await loginByPhoneApi(req)
    setToken(res.token)
    token.value = res.token
  }

  // 三方账号登录
  const loginBySocial = async (source: string, req: any) => {
    const res = await loginBySocialApi(source, req)
    setToken(res.token)
    token.value = res.token
  }

  // 退出账号
  const logout = async () => {
    token.value = ''
    userInfo.value = null
    permissions.value = new Set()
    try {
      await logoutApi()
    } catch (err) {
      console.warn('退出登录失败: ', err)
    }
    clearToken()
    useTabsStore().reset()
    useRouteStore().initialized = false
    resetRouter()
  }

  return {
    userInfo,
    permissions,
    refreshUserInfo,
    hasPermission,
    hasAnyPermission,
    loginByAccount,
    loginByPhone,
    loginBySocial,
    logout,
  }
})
